/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef VIDEO_CODEC_SAMPLE_PLAYER_NATIVE_H
#define VIDEO_CODEC_SAMPLE_PLAYER_NATIVE_H

#include <js_native_api.h>
#include <js_native_api_types.h>
#include <memory>
#include <uv.h>
#include "napi/native_api.h"
#include "Player.h"
#include "dfx/error/AVCodecSampleError.h"
#include "AVCodecSampleLog.h"
#include "PluginManager.h"
#include "i_av_decoder_engine.h"
#include "i_av_encoder_engine.h"

class DecodeCallback : public AVDecodeCallback {
public:
    void OnDecodeFrame(uint64_t pts) override {};
    void OnDecodeStatus(CodecStatus status) override;
};

class DecodeCallbackConcurrency : public AVDecodeCallback {
public:
    void OnDecodeFrame(uint64_t pts) override {};
    void OnDecodeStatus(CodecStatus status) override;
};

class EncodeCallback : public AVEncodeCallback {
public:
    void OnEncodeFrame(uint64_t pts) override {};
    void OnEncodeStatus(CodecStatus result) override {};
};

class PlayerNative {
public:
    static napi_value Play(napi_env env, napi_callback_info info);
    static napi_value Export(napi_env env, napi_callback_info info);
    static napi_value Test(napi_env env, napi_callback_info info);
    static napi_value TestInner(SampleInfo sampleInfo);
    static void WaitForPreviewDone();
    static void WaitForExportDone();
    static void TestPreviewPrepare(const SampleInfo &sampleInfo, const AVEncodeParam& encodeParam, int32_t fd);
    static void TestExportPrepare(const SampleInfo &sampleInfo, const AVEncodeParam& encodeParam, int32_t fd);
    static void TestPreviewSeek(const SampleInfo &sampleInfo, const AVEncodeParam& encodeParam, int32_t fd);
    static void TestPreviewAddAudio(const SampleInfo &sampleInfo, const AVEncodeParam& encodeParam, int32_t fd);
    static void TestPreviewMuteAudio(const SampleInfo &sampleInfo, const AVEncodeParam& encodeParam, int32_t fd);
    static void TestExportSeek(const SampleInfo &sampleInfo, const AVEncodeParam& encodeParam, int32_t fd);
    static void TestExportAddAudio(const SampleInfo &sampleInfo, const AVEncodeParam& encodeParam, int32_t fd);
    static void TestExportUnselectAudio(const SampleInfo &sampleInfo, const AVEncodeParam& encodeParam, int32_t fd);
    static void TestPreviewDifferentAudioFormats(const SampleInfo &sampleInfo,
        const AVEncodeParam& encodeParam, int32_t fd);
    static void TestExportDifferentAudioFormats(const SampleInfo &sampleInfo,
        const AVEncodeParam& encodeParam, int32_t fd);
    static void TestLongTimePreviewing(const SampleInfo &sampleInfo, const AVEncodeParam& encodeParam, int32_t fd);
    static void TestLongTimeExporting(const SampleInfo &sampleInfo, const AVEncodeParam& encodeParam, int32_t fd);
    static void TestLongTimeConcurrency(const SampleInfo &sampleInfo, const AVEncodeParam& encodeParam, int32_t fd);
    static void TestDiffVideoFormatPreviewing(SampleInfo &sampleInfo, const AVEncodeParam& encodeParam, int32_t fd);
    static void TestDiffVideoFormatExporting(SampleInfo &sampleInfo, const AVEncodeParam& encodeParam, int32_t fd);
    
    static std::shared_ptr<IAVDecoderEngine> decoderEngine_;
    static std::shared_ptr<IAVEncoderEngine> encoderEngine_;
    static std::shared_ptr<DecodeCallback> decodeCb_;
    static std::shared_ptr<EncodeCallback> encodeCb_;
    static bool isPreview_;
    static std::condition_variable catchEOSCond_;
    static std::mutex catchEOSMutex_;
    static bool isEOSCatched_;
    
    static std::shared_ptr<IAVDecoderEngine> decoderEngineConcurrency_;
    static std::shared_ptr<IAVEncoderEngine> encoderEngineConcurrency_;
    static std::shared_ptr<DecodeCallbackConcurrency> decodeCbConcurrency_;
    static std::shared_ptr<EncodeCallback> encodeCbConcurrency_;
    static bool isPreviewConcurrency_;
    static std::condition_variable catchEOSCondConcurrency_;
    static std::mutex catchEOSMutexConcurrency_;
    static bool isEOSCatchedConcurrency_;
};
#endif // VIDEO_CODEC_SAMPLE_PLAYER_NATIVE_H